﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp;
using System.IO;
using Microsoft.CodeAnalysis;

namespace FanaticToy.Core.AnaemiaExtractor
{
    //public class ExtractorModel
    //{
    //    public string Name { get; set; }
    //}

    ///<summary>提取器。</summary>
    public class Extractor
    {

        ///<summary>提取并复制当前的贫血模型。</summary>
        public string Extract(string filePath)
        {
            if (filePath.EndsWith(".cs") == false) return null;
            var text = File.ReadAllText(filePath);
            var tree = CSharpSyntaxTree.ParseText(text);

            var classDeclare = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().FirstOrDefault();

            if (classDeclare == null) return null;

            var propertyDeclares = classDeclare.DescendantNodes().OfType<PropertyDeclarationSyntax>();

            if (propertyDeclares == null) return null;
            if (propertyDeclares.Count() == 0) return null;

            var modelClassBuilder = new StringBuilder();
            var ctorBuilder = new StringBuilder();
            var exportBuilder = new StringBuilder();

            var className = classDeclare.Identifier.Text;
            var modelName = TransferOriginName(className);

            modelClassBuilder.AppendLine($"public class {modelName}");
            modelClassBuilder.AppendLine($"{{");

            ctorBuilder.AppendLine($"public {className}({modelName} model)");
            ctorBuilder.AppendLine($"{{");

            exportBuilder.AppendLine($"public {modelName} ExportModel()");
            exportBuilder.AppendLine($"{{");
            exportBuilder.AppendLine($"return new {modelName}()");
            exportBuilder.AppendLine($"{{");

            foreach (var propDecleare in propertyDeclares)
            {
                if (propDecleare.Modifiers
                    .Any(i =>
                    i.IsKind(SyntaxKind.PrivateKeyword) ||
                    i.IsKind(SyntaxKind.OverrideKeyword) ||
                    i.IsKind(SyntaxKind.StaticKeyword)))

                    continue;

                var propName = propDecleare.Identifier.Text;
                var propType = propDecleare.Type.ToString();

                modelClassBuilder.AppendLine($"public {propType} {propName} {{get; set;}}");

                ctorBuilder.AppendLine($"{propName} = model.{propName};");
                exportBuilder.AppendLine($"{propName} = this.{propName},");

            }
            modelClassBuilder.AppendLine($"}}");
            ctorBuilder.AppendLine($"}}");

            exportBuilder.AppendLine($"}};");
            exportBuilder.AppendLine($"}}");

            var finalBuilder = new StringBuilder();

            finalBuilder.AppendLine(modelClassBuilder.ToString());
            finalBuilder.AppendLine(ctorBuilder.ToString());
            finalBuilder.AppendLine(exportBuilder.ToString());

            return finalBuilder.ToString();
        }

        ///<summary>转换原来模块的类的名称。</summary>
        private string TransferOriginName(string originName)
        {
            var endWithList = new[] { "ViewModel", "Model", };
            var nextWithList = new[] { "Model", "", };

            for (int i = 0; i < endWithList.Length; i++)
            {
                var item = endWithList[i];
                if (originName.EndsWith(item))
                {
                    return originName.Substring(0, originName.Length - item.Length) + nextWithList[i];
                }
            }

            return originName + "Model";
        }


    }
}
